import requests
import time
import webbrowser
from urllib.parse import urlencode
from config import ConfigManager

class AuthManager:
    def __init__(self):
        self.config = ConfigManager()
    
    def is_configured(self):
        """检查是否已配置客户端信息"""
        client_id = self.config.get_client_id()
        client_secret = self.config.get_client_secret()
        return bool(client_id and client_secret)
    
    def refresh_token(self):
        """刷新访问令牌"""
        tokens = self.config.load_tokens()
        if not tokens or 'refresh_token' not in tokens:
            print("❌ 未找到刷新令牌")
            return False
            
        refresh_token = tokens['refresh_token']
        client_id = self.config.get_client_id()
        client_secret = self.config.get_client_secret()
        
        if not client_id or not client_secret:
            print("❌ 未配置客户端信息")
            return False
            
        url = "https://openapi.baidu.com/oauth/2.0/token"
        params = {
            "grant_type": "refresh_token",
            "refresh_token": refresh_token,
            "client_id": client_id,
            "client_secret": client_secret
        }
        
        try:
            response = requests.get(url, params=params)
            result = response.json()
            
            if 'error' in result:
                print(f"刷新令牌失败: {result.get('error_description', '未知错误')}")
                return False
                
            # 保存新令牌
            new_tokens = {
                'access_token': result['access_token'],
                'refresh_token': result.get('refresh_token', refresh_token),
                'expires_at': time.time() + result['expires_in'],
                'scope': result.get('scope', ''),
                'session_key': result.get('session_key', ''),
                'session_secret': result.get('session_secret', '')
            }
            
            self.config.save_tokens(new_tokens)
            print("✅ 令牌刷新成功")
            return True
        except Exception as e:
            print(f"刷新令牌错误: {e}")
            return False
    
    def authenticate(self):
        """进行OAuth认证"""
        # 检查是否已配置客户端信息
        client_id = self.config.get_client_id()
        client_secret = self.config.get_client_secret()
        
        if not client_id or not client_secret:
            print("❌ 请先配置客户端信息")
            print("请运行: config set client_id YOUR_CLIENT_ID")
            print("        config set client_secret YOUR_CLIENT_SECRET")
            return False
        
        # 构建授权URL
        auth_url = "https://openapi.baidu.com/oauth/2.0/authorize"
        params = {
            "response_type": "code",
            "client_id": client_id,
            "redirect_uri": self.config.get_redirect_uri(),
            "scope": "basic,netdisk",
            "display": "popup"
        }
        
        full_url = f"{auth_url}?{urlencode(params)}"
        print(f"请访问以下URL进行授权:\n{full_url}")
        
        # 尝试自动打开浏览器
        try:
            webbrowser.open(full_url)
        except:
            pass
        
        # 获取授权码
        auth_code = input("请输入授权码: ").strip()
        
        if not auth_code:
            print("❌ 授权码不能为空")
            return False
        
        # 交换访问令牌
        return self._exchange_token(auth_code)
    
    def _exchange_token(self, auth_code):
        """使用授权码交换访问令牌"""
        url = "https://openapi.baidu.com/oauth/2.0/token"
        params = {
            "grant_type": "authorization_code",
            "code": auth_code,
            "client_id": self.config.get_client_id(),
            "client_secret": self.config.get_client_secret(),
            "redirect_uri": self.config.get_redirect_uri()
        }
        
        try:
            response = requests.get(url, params=params)
            result = response.json()
            
            if 'error' in result:
                print(f"获取令牌失败: {result.get('error_description', '未知错误')}")
                return False
                
            # 保存令牌
            tokens = {
                'access_token': result['access_token'],
                'refresh_token': result['refresh_token'],
                'expires_at': time.time() + result['expires_in'],
                'scope': result.get('scope', ''),
                'session_key': result.get('session_key', ''),
                'session_secret': result.get('session_secret', '')
            }
            
            self.config.save_tokens(tokens)
            print("✅ 认证成功")
            return True
        except Exception as e:
            print(f"获取令牌错误: {e}")
            return False
    
    def get_access_token(self):
        """获取当前访问令牌"""
        tokens = self.config.load_tokens()
        if tokens and 'access_token' in tokens:
            # 检查令牌是否过期
            expires_at = tokens.get('expires_at', 0)
            if time.time() < expires_at - 300:  # 提前5分钟检查
                return tokens['access_token']
            else:
                # 令牌即将过期，尝试刷新
                if self.refresh_token():
                    tokens = self.config.load_tokens()
                    return tokens.get('access_token')
        return None
    
    def configure(self, client_id, client_secret, redirect_uri='oob'):
        """配置客户端信息"""
        config_data = {
            'client_id': client_id,
            'client_secret': client_secret,
            'redirect_uri': redirect_uri
        }
        self.config.save_config(config_data)
        print("✅ 客户端配置已保存")

    def configure_old(self, client_id, client_secret, redirect_uri='oob'):
        """配置客户端信息"""
        config_data = {
            'client_id': client_id,
            'client_secret': client_secret,
            'redirect_uri': redirect_uri
        }
        self.config.save_config(config_data)
        print("✅ 客户端配置已保存")
    
    def clear_client_config(self):
        """清除客户端配置"""
        config_data = {
            'client_id': '',
            'client_secret': '',
            'redirect_uri': 'urn:ietf:wg:oauth:2.0:oob'
        }
        self.config.save_config(config_data)
        
    def logout(self):
        """清除认证信息"""
        try:
            self.config.save_tokens({})
            return True
        except Exception as e:
            print(f"登出错误: {e}")
            return False
    
    def get_token_expiration(self):
        """获取令牌过期时间"""
        tokens = self.config.load_tokens()
        if tokens and 'expires_at' in tokens:
            return tokens['expires_at']
        return None
